/*
 *所有关于yuanfa_pro_info类的业务代码应在此处编写
*可使用repository.调用常用方法，获取EF/Dapper等信息
*如果需要事务请使用repository.DbContextBeginTransaction
*也可使用DBServerProvider.手动获取数据库相关信息
*用户信息、权限、角色等使用UserContext.Current操作
*yuanfa_pro_infoService对增、删、改查、导入、导出、审核业务代码扩展参照ServiceFunFilter
*/
using DGZImp.Core.BaseProvider;
using DGZImp.Core.Extensions.AutofacManager;
using ATkg.BizAppProject.DomainModels;
using System.Linq;
using DGZImp.Core.Utilities;
using System.Linq.Expressions;
using DGZImp.Core.Extensions;

using Microsoft.Extensions.DependencyInjection;
using Microsoft.AspNetCore.Http;
using ATkg.BizAppProject.IRepositories;
using DGZImp.Core.Exceptions;
using Newtonsoft.Json.Linq;
using DGZImp.Core.EFDbContext;
using Microsoft.Extensions.Configuration;
using DGZImp.Core.DbSqlSugar;
using System.Globalization;
using DocumentFormat.OpenXml.InkML;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using ATkg.BizAppProject.Controllers;
using DGZImp.Core.ManageUser;
namespace ATkg.BizAppProject.Services
{
    public partial class yuanfa_pro_infoService
    {
        private readonly IHttpContextAccessor _httpContextAccessor;
        private readonly Iyuanfa_pro_infoRepository _repository;//访问数据库
        public ISqlSugarClient Db = AutofacContainerModule.GetService<ServiceDbContext>()?.SqlSugarClient;
        public IConfiguration _config;
        public HttpClient client = null;
        public static IHttpClientFactory _httpClientFactory { get; set; }

        public AmesSyncService ames = AutofacContainerModule.GetService<AmesSyncService>();

        [ActivatorUtilitiesConstructor]
        public yuanfa_pro_infoService(
            Iyuanfa_pro_infoRepository dbRepository,
            IHttpContextAccessor httpContextAccessor
            )
        : base(dbRepository)
        {
            _httpContextAccessor = httpContextAccessor;
            _repository = dbRepository;
            //多租户会用到这init代码，其他情况可以不用
            //base.Init(dbRepository);
        }

        public UserInfo userInfo = UserContext.Current.UserInfo;
        public override PageGridData<yuanfa_pro_info> GetPageData(PageDataOptions options)
        {
            QueryRelativeExpression = queryable =>
            {
                //Console.WriteLine();
                //queryable.Where(a => a.CreateId == userInfo.UserId);
                //return queryable;

                // 1. 先获取当前用户的真实姓名（确保 UserTrueName 不为 null，避免空引用）
                string currentUserName = userInfo?.UserTrueName?.Trim() ?? string.Empty;

                // 2. 核心条件判断：是否需要取全部数据
                bool isTakeAll = false;

                // 条件1：创建人名包含“管理员” → 取全部
                if (currentUserName.Contains("管理员", StringComparison.OrdinalIgnoreCase)) // 忽略大小写，按需删除
                {
                    isTakeAll = true;
                }
                // 条件2：不包含“管理员”，但包含指定人名“谢连刚” → 取全部
                else if (currentUserName.Contains("谢连刚", StringComparison.OrdinalIgnoreCase)) // 忽略大小写，按需删除
                {
                    isTakeAll = true;
                }

                // 3. 不需要取全部时，追加过滤条件：UserTrueName == Creator
                if (!isTakeAll)
                {
                    // 注意：确保实体类 yuanfa_pro_info 中存在 UserTrueName 和 Creator 两个属性（字段名需匹配）
                    queryable = queryable.Where(a => a.Creator == userInfo.UserTrueName);
                }

                // 4. 原有条件：CreateId == 当前用户ID（始终保留，除非需求是“取全部”时忽略该条件）
                // 若“取全部”时需要忽略 CreateId 过滤，可将这行移到 !isTakeAll 分支内
                

                return queryable;

            };
            return base.GetPageData(options);
        }

        public async Task<object> get_yf_from_mes(string proname)
        {
            Console.WriteLine("进来了！！！");
            ames.userName = "duyang@atmcn.com";
            ames.password = "Du123456*";
            ames.url = "http://10.7.1.3/jsonrpc";
            ames.db = "atm";

            //var typeArray = new[] { "final" };

            var qDomain = new List<object> {
                new List<object> { "order_type", "=","product" },
                new List<object> { "original_product_code", "ilike", proname }
            };
            var qFields = new List<string> {
                "id", "name", "partner_blueprint_no"
            };
            var qPage = new
            { };
            var resp = await ames.Get_info_gzd("atm.plm.top", qDomain, qFields, qPage);
            if (resp.ContainsKey("error"))
            {
                var message = $"【拉取单据】{resp["error"].ToString()}";
                throw new AppException(message);
            }
            var res = (JArray)resp["result"];
            Console.WriteLine(res.Count);
            if (res == null || res.Count <= 0)
            {
                return 0;
            }
            //List<SteelName> list_out_o = new List<SteelName>();
            var final_data_info1 = new List<subcontracting_plan>();
            var all_in_list = new List<object>();
            for (int i = 0; i < res.Count; i++)
            {
                var per_info_list = new List<object>();
                Console.WriteLine(res[i]);
                var per_ = res[i];
                int product_nameid = (int)per_["id"];
                Console.WriteLine(product_nameid);
                Console.WriteLine(per_["name"].ToString());
                //var id_lot = lot_dis[0];
                var qDomain12 = new List<object> {
                    new List<object> { "top_id", "=", product_nameid },
                };
                var qFields12 = new List<string> { "name", "final_qty_available", "manufacturing_incoming_final_qty" };

                var qPage12 = new { context = new { lang = "zh_CN", tz = "Asia/Shanghai", no_scrap = true }, limit = 10000, offset = 0 };

                var resp12 = await ames.Get_info_gzd("product.product", qDomain12, qFields12, qPage12);
                var originalList = (JArray)resp12["result"];
                Console.WriteLine(originalList);
                Console.WriteLine("LLLLLL");

                per_info_list.Add(per_["name"].ToString());  //新增


                // 辅助方法：判断字符串中第一个"/"之后的内容是否包含"N"
                bool HasNAfterFirstSlash(string name)
                {
                    int firstSlashIndex = name.IndexOf('/');
                    if (firstSlashIndex == -1)
                        return false; // 不含"/"，自然没有第一个"/"后的N
                                      // 截取第一个"/"之后的内容，判断是否含"N"
                    string partAfterFirstSlash = name.Substring(firstSlashIndex + 1);
                    return partAfterFirstSlash.Contains("N");
                }

                // 第一步：生成result列表（排除条件更新为：第一个"/"后含N的项）
                var result = originalList
                    .Where(item =>
                        !item["name"].ToString().Contains("废料")  // 排除废料
                        && !HasNAfterFirstSlash(item["name"].ToString())  // 排除第一个"/"后含N的项
                        && !item["name"].ToString().Contains("细粉") // 排除细粉
                        && !item["name"].ToString().Contains("氢破") // 排除细粉
                        && !item["name"].ToString().Contains("气流磨") // 排除细粉
                    )
                    .Select(item =>
                    {
                        string name = item["name"].ToString();
                        int slashCount = name.Count(c => c == '/');
                        if (slashCount > 1)
                        {
                            int firstSlash = name.IndexOf('/');
                            int secondSlash = name.IndexOf('/', firstSlash + 1);
                            return secondSlash != -1 ? name.Substring(0, secondSlash) : name;
                        }
                        return name;
                    })
                    .Distinct()
                    .ToList();

                // 第二步：为每个result元素计算在库和在线数量
                var resultWithQuantities = new List<Dictionary<string, object>>();
                foreach (var resItem in result)
                {
                    bool hasSlash = resItem.Contains("/");

                    if (hasSlash)
                    {
                        // 特殊处理：含"毛坯"的result项，合并压坯数据
                        if (resItem.Contains("毛坯"))
                        {
                            // 收集所有压坯相关数据（排除废料、第一个/后含N、细粉）
                            var pressedItems = originalList
                                .Where(item =>
                                    !item["name"].ToString().Contains("废料")
                                    && !HasNAfterFirstSlash(item["name"].ToString())
                                    && !item["name"].ToString().Contains("细粉")
                                    && item["name"].ToString().Contains("压坯")
                                )
                                .ToList();
                            // 压坯总和：final_qty_available + manufacturing_incoming_final_qty
                            double pressedSum = pressedItems.Sum(item =>
                                (int)item["final_qty_available"] + (double)item["manufacturing_incoming_final_qty"]);

                            // 毛坯自身数据
                            var blankItems = originalList
                                .Where(item =>
                                    !item["name"].ToString().Contains("废料")
                                    && !HasNAfterFirstSlash(item["name"].ToString())
                                    && !item["name"].ToString().Contains("细粉")
                                    && item["name"].ToString() == resItem  // 完全匹配毛坯项
                                )
                                .ToList();
                            // 毛坯在库数量：自身final_qty_available
                            int blankStock = blankItems.Sum(item => (int)item["final_qty_available"]);
                            // 毛坯在线补充：自身manufacturing_incoming_final_qty
                            double blankManufacturing = blankItems.Sum(item => (double)item["manufacturing_incoming_final_qty"]);

                            // 最终在线数量 = 压坯总和 + 毛坯manufacturing
                            double finalOnline = pressedSum + blankManufacturing;

                            resultWithQuantities.Add(new Dictionary<string, object>
                            {
                                { "名称", resItem },
                                { "在库数量", blankStock },
                                { "在线数量", finalOnline },
                                { "客户图纸号", per_["partner_blueprint_no"].ToString() },
                                { "产品代码", per_["name"].ToString() }
                            });
                        }
                        else
                        {
                            // 含"/"但不含"毛坯"的项，按规则计算
                            var relatedItems = originalList
                                .Where(item =>
                                    !item["name"].ToString().Contains("废料")
                                    && !HasNAfterFirstSlash(item["name"].ToString())
                                    && !item["name"].ToString().Contains("细粉")
                                    && item["name"].ToString().Contains(resItem)
                                )
                                .ToList();

                            var containsButNotEqual = relatedItems
                                .Where(item => item["name"].ToString() != resItem)
                                .ToList();
                            double onlineFromCondition1 = containsButNotEqual.Sum(item =>
                                (int)item["final_qty_available"] + (double)item["manufacturing_incoming_final_qty"]);

                            var exactlyEqual = relatedItems
                                .FirstOrDefault(item => item["name"].ToString() == resItem);
                            int stockQuantity = exactlyEqual != null ? (int)exactlyEqual["final_qty_available"] : 0;
                            double manufacturingIncoming = exactlyEqual != null ? (double)exactlyEqual["manufacturing_incoming_final_qty"] : 0;

                            double finalOnlineQuantity = onlineFromCondition1 + manufacturingIncoming;

                            resultWithQuantities.Add(new Dictionary<string, object>
                            {
                                { "名称", resItem },
                                { "在库数量", stockQuantity },
                                { "在线数量", finalOnlineQuantity },
                                { "客户图纸号", per_["partner_blueprint_no"].ToString() },
                                { "产品代码", per_["name"].ToString() }
                            });
                        }
                    }
                    else
                    {
                        // 不含"/"的项，处理含N的数据（仅统计第一个"/"后含N的项）
                        var itemsWithN = originalList
                            .Where(item =>
                                !item["name"].ToString().Contains("废料")
                                && !item["name"].ToString().Contains("细粉")
                                && HasNAfterFirstSlash(item["name"].ToString())  // 仅第一个"/"后含N的项
                                && item["name"].ToString().Contains(resItem)  // 与当前resItem相关
                            )
                            .ToList();
                        double sumWithN = itemsWithN.Sum(item =>
                            (int)item["final_qty_available"] + (double)item["manufacturing_incoming_final_qty"]);

                        var itemsWithoutSlashAndN = originalList
                            .Where(item =>
                                !item["name"].ToString().Contains("废料")
                                && !HasNAfterFirstSlash(item["name"].ToString())
                                && !item["name"].ToString().Contains("细粉")
                                && item["name"].ToString() == resItem
                            )
                            .ToList();
                        double onlineQuantity = sumWithN + itemsWithoutSlashAndN.Sum(item => (double)item["manufacturing_incoming_final_qty"]);
                        int stockQuantity = itemsWithoutSlashAndN.Sum(item => (int)item["final_qty_available"]);

                        resultWithQuantities.Add(new Dictionary<string, object>
                {
                    { "名称", resItem },
                    { "在库数量", stockQuantity },
                    { "在线数量", onlineQuantity },
                    { "客户图纸号", per_["partner_blueprint_no"].ToString() },
                    { "产品代码", per_["name"].ToString() }
                });
                    }
                }
                all_in_list.Add(resultWithQuantities);
            }

            //await Db.DoInsertAsync<subcontracting_plan>(final_data_info1);

            return all_in_list;
        }


        public async Task<object> get_yf_from_mes_ak(string proname)
        {
            Console.WriteLine("进来了！！！");
            ames.userName = "duyang@atmcn.com";
            ames.password = "Dy123456";
            ames.url = "http://10.7.1.4/jsonrpc";
            ames.db = "sd";

            //var typeArray = new[] { "final" };

            var qDomain = new List<object> {
                new List<object> { "order_type", "=","product" },
                new List<object> { "original_product_code", "ilike", proname }
            };
            var qFields = new List<string> {
                "id", "name","partner_blueprint_no"
            };
            var qPage = new
            { };
            var resp = await ames.Get_info_gzd("atm.plm.top", qDomain, qFields, qPage);
            if (resp.ContainsKey("error"))
            {
                var message = $"【拉取单据】{resp["error"].ToString()}";
                throw new AppException(message);
            }
            var res = (JArray)resp["result"];
            Console.WriteLine(res.Count);
            if (res == null || res.Count <= 0)
            {
                return 0;
            }
            //List<SteelName> list_out_o = new List<SteelName>();
            var final_data_info1 = new List<subcontracting_plan>();
            var all_in_list = new List<object>();
            for (int i = 0; i < res.Count; i++)
            {
                var per_info_list = new List<object>();
                Console.WriteLine(res[i]);
                var per_ = res[i];
                int product_nameid = (int)per_["id"];
                Console.WriteLine(product_nameid);
                Console.WriteLine(per_["name"].ToString());
                //var id_lot = lot_dis[0];
                var qDomain12 = new List<object> {
                    new List<object> { "top_id", "=", product_nameid },
                };
                var qFields12 = new List<string> { "name", "final_qty_available", "manufacturing_incoming_final_qty" };

                var qPage12 = new { context = new { lang = "zh_CN", tz = "Asia/Shanghai", no_scrap = true }, limit = 10000, offset = 0 };

                var resp12 = await ames.Get_info_gzd("product.product", qDomain12, qFields12, qPage12);
                var originalList = (JArray)resp12["result"];
                Console.WriteLine(originalList);
                Console.WriteLine("LLLLLL");

                per_info_list.Add(per_["name"].ToString());  //新增


                // 辅助方法：判断字符串中第一个"/"之后的内容是否包含"N"
                bool HasNAfterFirstSlash(string name)
                {
                    int firstSlashIndex = name.IndexOf('/');
                    if (firstSlashIndex == -1)
                        return false; // 不含"/"，自然没有第一个"/"后的N
                                      // 截取第一个"/"之后的内容，判断是否含"N"
                    string partAfterFirstSlash = name.Substring(firstSlashIndex + 1);
                    return partAfterFirstSlash.Contains("N");
                }

                // 第一步：生成result列表（排除条件更新为：第一个"/"后含N的项）
                var result = originalList
                    .Where(item =>
                        !item["name"].ToString().Contains("废料")  // 排除废料
                        && !HasNAfterFirstSlash(item["name"].ToString())  // 排除第一个"/"后含N的项
                        && !item["name"].ToString().Contains("细粉") // 排除细粉
                         && !item["name"].ToString().Contains("压坯") // 排除细粉
                    )
                    .Select(item =>
                    {
                        string name = item["name"].ToString();
                        int slashCount = name.Count(c => c == '/');
                        if (slashCount > 1)
                        {
                            int firstSlash = name.IndexOf('/');
                            int secondSlash = name.IndexOf('/', firstSlash + 1);
                            return secondSlash != -1 ? name.Substring(0, secondSlash) : name;
                        }
                        return name;
                    })
                    .Distinct()
                    .ToList();

                // 第二步：为每个result元素计算在库和在线数量
                var resultWithQuantities = new List<Dictionary<string, object>>();
                foreach (var resItem in result)
                {
                    bool hasSlash = resItem.Contains("/");

                    if (hasSlash)
                    {
                        // 特殊处理：含"毛坯"的result项，合并压坯数据
                        if (resItem.Contains("毛坯"))
                        {
                            // 收集所有压坯相关数据（排除废料、第一个/后含N、细粉）
                            var pressedItems = originalList
                                .Where(item =>
                                    !item["name"].ToString().Contains("废料")
                                    && !HasNAfterFirstSlash(item["name"].ToString())
                                    && !item["name"].ToString().Contains("细粉")
                                    && item["name"].ToString().Contains("压坯")
                                )
                                .ToList();
                            // 压坯总和：final_qty_available + manufacturing_incoming_final_qty
                            double pressedSum = pressedItems.Sum(item =>
                                (int)item["final_qty_available"] + (double)item["manufacturing_incoming_final_qty"]);

                            // 毛坯自身数据
                            var blankItems = originalList
                                .Where(item =>
                                    !item["name"].ToString().Contains("废料")
                                    && !HasNAfterFirstSlash(item["name"].ToString())
                                    && !item["name"].ToString().Contains("细粉")
                                    && item["name"].ToString() == resItem  // 完全匹配毛坯项
                                )
                                .ToList();
                            // 毛坯在库数量：自身final_qty_available
                            int blankStock = blankItems.Sum(item => (int)item["final_qty_available"]);
                            // 毛坯在线补充：自身manufacturing_incoming_final_qty
                            double blankManufacturing = blankItems.Sum(item => (double)item["manufacturing_incoming_final_qty"]);

                            // 最终在线数量 = 压坯总和 + 毛坯manufacturing
                            double finalOnline = pressedSum + blankManufacturing;

                            resultWithQuantities.Add(new Dictionary<string, object>
                    {
                        { "名称", resItem },
                        { "在库数量", blankStock },
                        { "在线数量", finalOnline },
                        { "客户图纸号", per_["partner_blueprint_no"].ToString() },
                        { "产品代码", per_["name"].ToString() }
                    });
                        }
                        else
                        {
                            // 含"/"但不含"毛坯"的项，按规则计算
                            var relatedItems = originalList
                                .Where(item =>
                                    !item["name"].ToString().Contains("废料")
                                    && !HasNAfterFirstSlash(item["name"].ToString())
                                    && !item["name"].ToString().Contains("细粉")
                                    && item["name"].ToString().Contains(resItem)
                                )
                                .ToList();

                            var containsButNotEqual = relatedItems
                                .Where(item => item["name"].ToString() != resItem)
                                .ToList();
                            double onlineFromCondition1 = containsButNotEqual.Sum(item =>
                                (int)item["final_qty_available"] + (double)item["manufacturing_incoming_final_qty"]);

                            var exactlyEqual = relatedItems
                                .FirstOrDefault(item => item["name"].ToString() == resItem);
                            int stockQuantity = exactlyEqual != null ? (int)exactlyEqual["final_qty_available"] : 0;
                            double manufacturingIncoming = exactlyEqual != null ? (double)exactlyEqual["manufacturing_incoming_final_qty"] : 0;

                            double finalOnlineQuantity = onlineFromCondition1 + manufacturingIncoming;

                            resultWithQuantities.Add(new Dictionary<string, object>
                    {
                        { "名称", resItem },
                        { "在库数量", stockQuantity },
                        { "在线数量", finalOnlineQuantity },
                        { "客户图纸号", per_["partner_blueprint_no"].ToString() },
                        { "产品代码", per_["name"].ToString() }
                    });
                        }
                    }
                    else
                    {
                        // 不含"/"的项，处理含N的数据（仅统计第一个"/"后含N的项）
                        var itemsWithN = originalList
                            .Where(item =>
                                !item["name"].ToString().Contains("废料")
                                && !item["name"].ToString().Contains("细粉")
                                && HasNAfterFirstSlash(item["name"].ToString())  // 仅第一个"/"后含N的项
                                && item["name"].ToString().Contains(resItem)  // 与当前resItem相关
                            )
                            .ToList();
                        double sumWithN = itemsWithN.Sum(item =>
                            (int)item["final_qty_available"] + (double)item["manufacturing_incoming_final_qty"]);

                        var itemsWithoutSlashAndN = originalList
                            .Where(item =>
                                !item["name"].ToString().Contains("废料")
                                && !HasNAfterFirstSlash(item["name"].ToString())
                                && !item["name"].ToString().Contains("细粉")
                                && item["name"].ToString() == resItem
                            )
                            .ToList();
                        double onlineQuantity = sumWithN + itemsWithoutSlashAndN.Sum(item => (double)item["manufacturing_incoming_final_qty"]);
                        int stockQuantity = itemsWithoutSlashAndN.Sum(item => (int)item["final_qty_available"]);

                        resultWithQuantities.Add(new Dictionary<string, object>
                {
                    { "名称", resItem },
                    { "在库数量", stockQuantity },
                    { "在线数量", onlineQuantity },
                    { "客户图纸号", per_["partner_blueprint_no"].ToString() },
                    { "产品代码", per_["name"].ToString() }
                });
                    }
                }
                all_in_list.Add(resultWithQuantities);
            }

            //await Db.DoInsertAsync<subcontracting_plan>(final_data_info1);

            return all_in_list;
        }



        public async Task<object> get_yf_from_mes_bf(string proname)
        {
            Console.WriteLine("进来了！！！");
            ames.userName = "duyang@atmcn.com";
            ames.password = "Antai@2025";
            ames.url = "http://10.16.12.80/jsonrpc";
            ames.db = "bt";

            //var typeArray = new[] { "final" };

            var qDomain = new List<object> {
                new List<object> { "original_product_code", "ilike", proname }
            };
            var qFields = new List<string> {
                "id", "name","partner_blueprint_no"
            };
            var qPage = new
            { };
            var resp = await ames.Get_info_gzd("atm.plm.top", qDomain, qFields, qPage);
            if (resp.ContainsKey("error"))
            {
                var message = $"【拉取单据】{resp["error"].ToString()}";
                throw new AppException(message);
            }
            var res = (JArray)resp["result"];
            Console.WriteLine(res.Count);
            if (res == null || res.Count <= 0)
            {
                return 0;
            }
            //List<SteelName> list_out_o = new List<SteelName>();
            var final_data_info1 = new List<subcontracting_plan>();
            var all_in_list = new List<object>();
            for (int i = 0; i < res.Count; i++)
            {
                var per_info_list = new List<object>();
                Console.WriteLine(res[i]);
                var per_ = res[i];
                int product_nameid = (int)per_["id"];
                Console.WriteLine(product_nameid);
                Console.WriteLine(per_["name"].ToString());
                //var id_lot = lot_dis[0];
                var qDomain12 = new List<object> {
                    new List<object> { "top_id", "=", product_nameid },
                };
                var qFields12 = new List<string> { "name", "final_qty_available", "manufacturing_incoming_final_qty" };

                //var qPage12 = new { context = new { lang = "zh_CN", tz = "Asia/Shanghai", no_scrap = true }, limit = 10000, offset = 0 };
                var qPage12 = new { context = new { lang = "zh_CN", tz = "Asia/Shanghai", no_scrap = true }, limit = 10000, offset = 0 };

                var resp12 = await ames.Get_info_gzd("product.product", qDomain12, qFields12, qPage12);
                var originalList = (JArray)resp12["result"];
                Console.WriteLine(originalList);
                Console.WriteLine("LLLLLL");

                per_info_list.Add(per_["name"].ToString());  //新增


                // 辅助方法：判断字符串中第一个"/"之后的内容是否包含"N"
                bool HasNAfterFirstSlash(string name)
                {
                    int firstSlashIndex = name.IndexOf('/');
                    if (firstSlashIndex == -1)
                        return false; // 不含"/"，自然没有第一个"/"后的N
                                      // 截取第一个"/"之后的内容，判断是否含"N"
                    string partAfterFirstSlash = name.Substring(firstSlashIndex + 1);
                    return partAfterFirstSlash.Contains("N");
                }

                // 第一步：生成result列表（排除条件更新为：第一个"/"后含N的项）
                var result = originalList
                    .Where(item =>
                        !item["name"].ToString().Contains("废料")  // 排除废料
                        && !HasNAfterFirstSlash(item["name"].ToString())  // 排除第一个"/"后含N的项
                        && !item["name"].ToString().Contains("细粉") // 排除细粉
                         && !item["name"].ToString().Contains("压坯") // 排除细粉
                    )
                    .Select(item =>
                    {
                        string name = item["name"].ToString();
                        int slashCount = name.Count(c => c == '/');
                        if (slashCount > 1)
                        {
                            int firstSlash = name.IndexOf('/');
                            int secondSlash = name.IndexOf('/', firstSlash + 1);
                            return secondSlash != -1 ? name.Substring(0, secondSlash) : name;
                        }
                        return name;
                    })
                    .Distinct()
                    .ToList();

                // 第二步：为每个result元素计算在库和在线数量
                var resultWithQuantities = new List<Dictionary<string, object>>();
                foreach (var resItem in result)
                {
                    bool hasSlash = resItem.Contains("/");

                    if (hasSlash)
                    {
                        // 特殊处理：含"毛坯"的result项，合并压坯数据
                        if (resItem.Contains("毛坯"))
                        {
                            // 收集所有压坯相关数据（排除废料、第一个/后含N、细粉）
                            var pressedItems = originalList
                                .Where(item =>
                                    !item["name"].ToString().Contains("废料")
                                    && !HasNAfterFirstSlash(item["name"].ToString())
                                    && !item["name"].ToString().Contains("细粉")
                                    && item["name"].ToString().Contains("压坯")
                                )
                                .ToList();
                            // 压坯总和：final_qty_available + manufacturing_incoming_final_qty
                            double pressedSum = pressedItems.Sum(item =>
                                (int)item["final_qty_available"] + (double)item["manufacturing_incoming_final_qty"]);

                            // 毛坯自身数据
                            var blankItems = originalList
                                .Where(item =>
                                    !item["name"].ToString().Contains("废料")
                                    && !HasNAfterFirstSlash(item["name"].ToString())
                                    && !item["name"].ToString().Contains("细粉")
                                    && item["name"].ToString() == resItem  // 完全匹配毛坯项
                                )
                                .ToList();
                            // 毛坯在库数量：自身final_qty_available
                            int blankStock = blankItems.Sum(item => (int)item["final_qty_available"]);
                            // 毛坯在线补充：自身manufacturing_incoming_final_qty
                            double blankManufacturing = blankItems.Sum(item => (double)item["manufacturing_incoming_final_qty"]);

                            // 最终在线数量 = 压坯总和 + 毛坯manufacturing
                            double finalOnline = pressedSum + blankManufacturing;

                            resultWithQuantities.Add(new Dictionary<string, object>
                    {
                        { "名称", resItem },
                        { "在库数量", blankStock },
                        { "在线数量", finalOnline },
                        { "客户图纸号", per_["partner_blueprint_no"].ToString() },
                        { "产品代码", per_["name"].ToString() }
                    });
                        }
                        else
                        {
                            // 含"/"但不含"毛坯"的项，按规则计算
                            var relatedItems = originalList
                                .Where(item =>
                                    !item["name"].ToString().Contains("废料")
                                    && !HasNAfterFirstSlash(item["name"].ToString())
                                    && !item["name"].ToString().Contains("细粉")
                                    && item["name"].ToString().Contains(resItem)
                                )
                                .ToList();

                            var containsButNotEqual = relatedItems
                                .Where(item => item["name"].ToString() != resItem)
                                .ToList();
                            double onlineFromCondition1 = containsButNotEqual.Sum(item =>
                                (int)item["final_qty_available"] + (double)item["manufacturing_incoming_final_qty"]);

                            var exactlyEqual = relatedItems
                                .FirstOrDefault(item => item["name"].ToString() == resItem);
                            int stockQuantity = exactlyEqual != null ? (int)exactlyEqual["final_qty_available"] : 0;
                            double manufacturingIncoming = exactlyEqual != null ? (double)exactlyEqual["manufacturing_incoming_final_qty"] : 0;

                            double finalOnlineQuantity = onlineFromCondition1 + manufacturingIncoming;

                            resultWithQuantities.Add(new Dictionary<string, object>
                    {
                        { "名称", resItem },
                        { "在库数量", stockQuantity },
                        { "在线数量", finalOnlineQuantity },
                        { "客户图纸号", per_["partner_blueprint_no"].ToString() },
                        { "产品代码", per_["name"].ToString() }
                    });
                        }
                    }
                    else
                    {
                        // 不含"/"的项，处理含N的数据（仅统计第一个"/"后含N的项）
                        var itemsWithN = originalList
                            .Where(item =>
                                !item["name"].ToString().Contains("废料")
                                && !item["name"].ToString().Contains("细粉")
                                && HasNAfterFirstSlash(item["name"].ToString())  // 仅第一个"/"后含N的项
                                && item["name"].ToString().Contains(resItem)  // 与当前resItem相关
                            )
                            .ToList();
                        double sumWithN = itemsWithN.Sum(item =>
                            (int)item["final_qty_available"] + (double)item["manufacturing_incoming_final_qty"]);

                        var itemsWithoutSlashAndN = originalList
                            .Where(item =>
                                !item["name"].ToString().Contains("废料")
                                && !HasNAfterFirstSlash(item["name"].ToString())
                                && !item["name"].ToString().Contains("细粉")
                                && item["name"].ToString() == resItem
                            )
                            .ToList();
                        double onlineQuantity = sumWithN + itemsWithoutSlashAndN.Sum(item => (double)item["manufacturing_incoming_final_qty"]);
                        int stockQuantity = itemsWithoutSlashAndN.Sum(item => (int)item["final_qty_available"]);

                        resultWithQuantities.Add(new Dictionary<string, object>
                {
                    { "名称", resItem },
                    { "在库数量", stockQuantity },
                    { "在线数量", onlineQuantity },
                    { "客户图纸号", per_["partner_blueprint_no"].ToString() },
                    { "产品代码", per_["name"].ToString() }
                });
                    }
                }
                all_in_list.Add(resultWithQuantities);
            }

            //await Db.DoInsertAsync<subcontracting_plan>(final_data_info1);

            return all_in_list;
        }



        public async Task<object> get_maopi_data()
        {
            DateTime now = DateTime.Now;
            string formattedTime = now.ToString("yyyy-MM-dd HH:mm:ss");
            // 安全转换（不抛异常）
            if (DateTime.TryParseExact(
                formattedTime,
                "yyyy-MM-dd HH:mm:ss",
                CultureInfo.InvariantCulture, // 忽略区域差异
                DateTimeStyles.None,
                out DateTime result_date))
            {
                Console.WriteLine($"转换成功: {result_date}");
            }
            else
            {
                Console.WriteLine("格式错误！");
            }
            Dictionary<string, string> weituo = new Dictionary<string, string>
                {
                    { "white", "倒角电镀" },
                    { "final", "检包" },
                };
            Dictionary<string, string> state = new Dictionary<string, string>
                {
                    { "none", "待判定" },
                    { "pending", "待处置" },
                    { "pass", "通过" },
                    { "inside_pass", "通过2" },
                    { "givein", "通过1" },
                    { "rework", "返工" },
                    { "scrap", "报废" },
                    { "recycle", "再利用" },
                    { "partial_fail", "部分失败" },
                    { "none_partial_fail", "待判定，部分失败" },
                    { "downshift", "降档使用" },
                    { "fail", "失败" }
                };
            Console.WriteLine("进来了！！！");
            ames.userName = "duyang@atmcn.com";
            ames.password = "Du123456*";
            //ames.url = "http://10.7.1.9/jsonrpc";
            //ames.db = "prd0803";

            var qDomain = new List<object> {
                new List<object> { "production_type", "=","blank" },
                new List<object> { "state", "=", "qc_pass"},
            };
            var qFields = new List<string> {
                "id", "name","qc_pass_time","product_id"
            };
            var qPage = new { context = new { lang = "zh_CN", tz = "Asia/Shanghai", bin_size = true }, limit = 10000, offset = 0 };
            //var qPage12 = new { context = new { lang = "zh_CN", tz = "Asia/Shanghai", no_scrap = true }, limit = 10000, offset = 0 };
            var resp = await ames.Get_info_gzd("mrp.production", qDomain, qFields, qPage);
            if (resp.ContainsKey("error"))
            {
                var message = $"【拉取单据】{resp["error"].ToString()}";
                throw new AppException(message);
            }
            var res = (JArray)resp["result"];
            if (res == null || res.Count <= 0)
            {
                return 0;
            }
            //List<SteelName> list_out_o = new List<SteelName>();
            var final_data_info1 = new List<object>();
            for (int i = 0; i < res.Count; i++)
            {
                var per_ = res[i];
                string originalTimeStr = per_["qc_pass_time"].ToString();
                var name = per_["name"].ToString();
                string timeFormat = "yyyy-MM-dd HH:mm:ss"; // 与原始字符串格式匹配
                CultureInfo ci = CultureInfo.InvariantCulture; // 固定格式，避免系统区域影响
                                                               // ===================== 场景1：原时间是 UTC 时区，转换为东八区 =====================
                var time_qc_pass = "";
                // 1. 解析字符串为 UTC 时间（DateTimeOffset 自带时区偏移，推荐使用）
                if (DateTimeOffset.TryParseExact(
                    originalTimeStr,
                    timeFormat,
                    ci,
                    DateTimeStyles.AssumeUniversal | DateTimeStyles.AdjustToUniversal,
                    out DateTimeOffset utcTime))
                {
                    // 2. 转换为东八区（Asia/Shanghai，包含夏令时自动适配）
                    TimeZoneInfo east8TimeZone = TimeZoneInfo.FindSystemTimeZoneById("China Standard Time");
                    DateTimeOffset east8Time = TimeZoneInfo.ConvertTime(utcTime, east8TimeZone);

                    // 输出结果（格式与原字符串一致）
                    string east8TimeStr = east8Time.ToString(timeFormat, ci);
                    time_qc_pass = east8TimeStr;
                }
                else
                {
                    Console.WriteLine("UTC 时间解析失败！");
                }

                var qDomain1 = new List<object> {
                new List<object> { "lot_id", "ilike", name },
                };
                var qFields1 = new List<string> {
                "id", "name","check_ids"
                };
                var qPage1 = new { context = new { lang = "zh_CN", tz = "Asia/Shanghai", bin_size = true }, limit = 10000, offset = 0 };
                //var qPage12 = new { context = new { lang = "zh_CN", tz = "Asia/Shanghai", no_scrap = true }, limit = 10000, offset = 0 };
                var resp1 = await ames.Get_info_gzd("quality.point", qDomain1, qFields1, qPage);
                var res1 = (JArray)resp1["result"];
                var check_ids = res1[0]["check_ids"];
                List<object> qDomain12 = check_ids.ToObject<List<object>>();
                var qFields12 = new List<string> { "quality_state", "id" };
                var resp12 = await ames.CallRead("quality.check", qDomain12, qFields12, "");
                var res12 = (JArray)resp12["result"];
                var count_TG = 0;
                for(int p_ = 0; p_ < res12.Count; p_++)
                {
                    var name_ = res12[p_]["quality_state"].ToString();   //item["name"].ToString().Contains("细粉")
                    if (state[name_].Contains("通过"))
                    {
                        count_TG += 1;
                    }
                }
                if(count_TG == res12.Count)
                {
                    List<object> per_info = new List<object>();
                    per_info.Add(name);
                    per_info.Add(time_qc_pass);
                    per_info.Add(per_["product_id"][1]);
                    final_data_info1.Add(per_info);
                }

            }
            return final_data_info1;
        }
    }
}
